package com.cleargroup.magic.cleara.c;

import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.os.Debug;

import com.cleargroup.magic.cleara.c.command.ReleaseUtil;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileReader;


public class RamUtil {

	public static long getFreeRam(Context context) {
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		MemoryInfo mi = new MemoryInfo();
		am.getMemoryInfo(mi);
		return Math.abs(mi.availMem);
	}

	public static long getTotalRam(Context context) {
		long res = -1;

		res = getTotalRam();

		if (res <= 0) {
			ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
			MemoryInfo mi = new MemoryInfo();
			am.getMemoryInfo(mi);
			res = Math.abs(mi.totalMem);
		}

		return res;
	}

	public static long getTotalRam() {
		long res = -1;
		FileReader fr = null;
		BufferedReader br = null;
		try {
			fr = new FileReader("proc/meminfo");
			br = new BufferedReader(fr);
			String line = br.readLine();
			res = Long.parseLong(line.replaceAll("\\s+", "")
					.replaceAll("[a-zA-Z]", "")
					.replaceAll(":", ""));
			res = Math.abs(res) * 1024;
		} catch (Throwable ignored) {
		} finally {
			ReleaseUtil.release(fr);
			ReleaseUtil.release(br);
		}
		return res;
	}

	/**
	 * http://hi.baidu.com/deep_pro/item/392097650d5003107ddecc00
	 * 
	 * [root@localhost proc]# cat /proc/1/statm 487 185 133 31 0 67 0
	 * �ܼ򵥵ط���7�����֣�ÿһ���ĵ�λ����һҳ ���������4KB�� �ֱ��� 1.size:���������ַ�ռ��С
	 * 2.Resident������ʹ�õ������ڴ��С 3.Shared������ҳ�� 4.Trs��������ӵ�еĿ�ִ�������ڴ��С
	 * 5.Lrs����ӳ������������ڴ�ռ�Ŀ�Ĵ�С 6.Drs��������ݶκ��û�̬��ջ�Ĵ�С 7.dt����ҳ����
	 * 
	 * @param pid
	 * @return
	 */
	public static long getProcessRam(Context context, int pid) {
		long result = 0;
		try {
			ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
			Debug.MemoryInfo[] mi = am.getProcessMemoryInfo(new int[] { pid });
			result = mi[0].getTotalPss() * 1024;
		} catch(Throwable t) {
		}
		return result;
	}

	public static int getProcessResidentRam(int pid) {
		int result = -1;
		FileInputStream fis = null;
		DataInputStream dis = null;
		try {
			String memory = "/proc/" + pid + "/statm";
			fis = new FileInputStream(memory);
			dis = new DataInputStream(fis);
			result = Integer.parseInt(dis.readLine().split("\\s+")[1]);
		} catch (Exception e) {
		} finally {
			ReleaseUtil.release(fis);
			ReleaseUtil.release(dis);
		}
		return result * 1024 / 4;
	}

	public static int getProcessVirtualRam(int pid) {
		int result = -1;
		FileInputStream fis = null;
		DataInputStream dis = null;
		try {
			String memory = "/proc/" + pid + "/statm";
			fis = new FileInputStream(memory);
			dis = new DataInputStream(fis);
			result = Integer.parseInt(dis.readLine().split("\\s+")[0]);
		} catch (Exception e) {
		} finally {
			ReleaseUtil.release(fis);
			ReleaseUtil.release(dis);
		}
		return result * 1024 / 4;
	}

	/**
	 * http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-
	 * of-my-application-in-android/2299813#2299813
	 * 
	 * @param context
	 * @param pid
	 * @return bytes
	 */
	public static long getDalvikPss(Context context, int pid) {
		long result = -1;
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		Debug.MemoryInfo[] mis = am.getProcessMemoryInfo(new int[] { pid });
		Debug.MemoryInfo mi = mis[0];
		result = mi.dalvikPss;
		return result * 1024;
	}

	/**
	 * 
	 * @param context
	 * @param pid
	 * @return bytes
	 */
	public static long getTotalPss(Context context, int pid) {
		long result = -1;
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		Debug.MemoryInfo[] mis = am.getProcessMemoryInfo(new int[] { pid });
		Debug.MemoryInfo mi = mis[0];
		result = mi.getTotalPss();
		return result * 1024;
	}

	/**
	 * 
	 * @param context
	 * @param pid
	 * @return bytes
	 */
	public static long getTotalSharedDirty(Context context, int pid) {
		long result = -1;
		int[] pids = new int[] { pid };
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		Debug.MemoryInfo[] mis = am.getProcessMemoryInfo(pids);
		Debug.MemoryInfo mi = mis[0];
		result = mi.getTotalSharedDirty();
		return result * 1024;
	}
}
